package de.ba.se.roboter.ui;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import java.util.Hashtable;

import javax.swing.DefaultListModel;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSlider;
import javax.swing.ListSelectionModel;

import de.ba.se.roboter.controller.MainController;
import de.ba.se.roboter.data.Robot;

/**
 * Das Steuerungspanel im Hauptfenster.
 * 
 * @author Sebastian Tönse
 *
 */
public class ControlPanel extends JPanel {
	
	/** @see java.io.Serializable */
	private static final long serialVersionUID = -6418707550840502941L;

	private JButton startButton;
	
	private JButton stopButton;
	
	private JButton stepButton;
	
	private final JLabel timeLabel = new JLabel("Geschwindigkeit");
	
	private JSlider timeSlider;
	
	private JList<String> stepList;
	
	private MainController controller;
	
	/**
	 * Der Konstruktor, dem der Controller zum Empfang der Events übergeben wird.
	 * @param controller Der Controller.
	 */
	public ControlPanel(MainController controller) {
		this.controller = controller;
		final JScrollPane scrollPane = new JScrollPane(getStepList());
		scrollPane.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() {
			@Override
	        public void adjustmentValueChanged(AdjustmentEvent e) {  
	            e.getAdjustable().setValue(e.getAdjustable().getMaximum());  
	        }
	    });
		final GroupLayout layout = new GroupLayout(this);
		setLayout(layout);
		layout.setAutoCreateContainerGaps(true);
		layout.setAutoCreateGaps(true);
		
		layout.linkSize(getStartButton(), getStopButton(), getStepButton());
		
		layout.setHorizontalGroup(layout.createParallelGroup(Alignment.CENTER)
				.addGroup(layout.createSequentialGroup()
					.addComponent(getStartButton(), GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE)
					.addComponent(getStopButton(), GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE)
					.addComponent(getStepButton(), GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE))
				.addComponent(timeLabel)	
				.addComponent(getTimeSlider())
				.addComponent(scrollPane));
		layout.setVerticalGroup(layout.createSequentialGroup()
			    .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
			    	.addComponent(getStartButton()).addComponent(getStopButton()).addComponent(getStepButton()))
			    .addComponent(timeLabel)
			    .addComponent(getTimeSlider())
			    .addComponent(scrollPane));
	}

	/**
	 * Button zum Starten des {@link Robot}
	 * @return Das Element.
	 */
	public JButton getStartButton() {
		if (startButton == null) {
			startButton = new JButton("Start");
			startButton.addActionListener(new ActionListener() {
				
				@Override
				public void actionPerformed(ActionEvent e) {
					controller.start(getTimeSlider().getValue());
				}
			});
		}
		return startButton;
	}

	/**
	 * Button zum Stoppen des {@link Robot}
	 * @return Das Element.
	 */
	public JButton getStopButton() {
		if (stopButton == null) {
			stopButton = new JButton("Stop");
			stopButton.addActionListener(new ActionListener() {
				
				@Override
				public void actionPerformed(ActionEvent e) {
					controller.stop();
				}
			});
		}
		return stopButton;
	}

	/**
	 * Button, um den {@link Robot} einen Schritt zu bewegen.
	 * @return Das Element.
	 */
	public JButton getStepButton() {
		if (stepButton == null) {
			stepButton = new JButton("Schritt");
			stepButton.addActionListener(new ActionListener() {
				
				@Override
				public void actionPerformed(ActionEvent e) {
					controller.step();
				}
			});
		}
		return stepButton;
	}

	/**
	 * Einstellung der Geschwindigkeit.
	 * @return Das Element.
	 */
	public JSlider getTimeSlider() {
		if (timeSlider == null) {
			timeSlider = new JSlider(JSlider.HORIZONTAL, 0, 10, 5);
			timeSlider.setPaintLabels(true);
			timeSlider.setSnapToTicks(true);
			timeSlider.setPaintTicks(true);
			timeSlider.setMajorTickSpacing(5);
			timeSlider.setMinorTickSpacing(1);
			timeSlider.setInverted(true);
			final Hashtable<Integer, JComponent> labels = new Hashtable<Integer, JComponent>();
			labels.put(0, new JLabel("schnell"));
			labels.put(5, new JLabel("normal"));
			labels.put(10, new JLabel("langsam"));
			timeSlider.setLabelTable(labels);
		}
		return timeSlider;
	}

	/**
	 * Log-Liste
	 * @return Das Element.
	 */
	public JList<String> getStepList() {
		if (stepList == null) {
			stepList = new  JList<String>();
			stepList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
			stepList.setModel(new DefaultListModel<String>());
		}
		return stepList;
	}
}
